From 9af364c3c4a0c798f74aba7a1d605d103c1632b9 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Fri, 6 May 2005 17:02:01 +0000 Subject: [PATCH] bitkeeper revision 1.1389.9.1 (427ba309i_zOrtoMDOTBwa5_vBiEXQ) Add support for privified mov-from-pmd Add counters for privified-fc and privified-cpuid Add optional support for counting addresses of privops Remove unnecessary PCI stuff Add optional heartbeat console output Signed-off by: Dan Magenheimer --- xen/arch/ia64/privop.c | 82 ++++++++++++++++++++++++++++++++--- xen/arch/ia64/vcpu.c | 41 ++++++++++-------- xen/arch/ia64/xenmisc.c | 69 +---------------------------- xen/arch/ia64/xentime.c | 11 +++++ xen/include/asm-ia64/config.h | 6 --- xen/include/asm-ia64/vcpu.h | 15 +++++++ 6 files changed, 126 insertions(+), 98 deletions(-) diff --git a/xen/arch/ia64/privop.c b/xen/arch/ia64/privop.c index 0b59b60ad8..11ef17310f 100644 --- a/xen/arch/ia64/privop.c +++ b/xen/arch/ia64/privop.c @@ -417,10 +417,17 @@ IA64FAULT priv_mov_from_pmc(VCPU *vcpu, INST64 inst) UINT64 val; IA64FAULT fault; - fault = vcpu_get_pmc(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val); - if (fault == IA64_NO_FAULT) - return vcpu_set_gr(vcpu, inst.M43.r1, val); - else return fault; + if (inst.M43.r1 > 63) { // privified mov from pmd + fault = vcpu_get_pmd(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val); + if (fault == IA64_NO_FAULT) + return vcpu_set_gr(vcpu, inst.M43.r1-64, val); + } + else { + fault = vcpu_get_pmc(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val); + if (fault == IA64_NO_FAULT) + return vcpu_set_gr(vcpu, inst.M43.r1, val); + } + return fault; } unsigned long from_cr_cnt[128] = { 0 }; @@ -531,6 +538,8 @@ struct { unsigned long bsw0; unsigned long bsw1; unsigned long cover; + unsigned long fc; + unsigned long cpuid; unsigned long Mpriv_cnt[64]; } privcnt = { 0 }; @@ -631,7 +640,11 @@ priv_handle_op(VCPU *vcpu, REGS *regs, int privlvl) else x6 = 0x1a; } } - privcnt.Mpriv_cnt[x6]++; + if (x6 == 52 && inst.M28.r3 > 63) + privcnt.fc++; + else if (x6 == 16 && inst.M43.r3 > 63) + privcnt.cpuid++; + else privcnt.Mpriv_cnt[x6]++; return (*pfunc)(vcpu,inst); break; case B: @@ -826,6 +839,12 @@ int dump_privop_counts(char *buf) if (privcnt.cover) s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.cover, "cover", (privcnt.cover*100L)/sum); + if (privcnt.fc) + s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.fc, + "privified-fc", (privcnt.fc*100L)/sum); + if (privcnt.cpuid) + s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.cpuid, + "privified-getcpuid", (privcnt.cpuid*100L)/sum); for (i=0; i < 64; i++) if (privcnt.Mpriv_cnt[i]) { if (!Mpriv_str[i]) s += sprintf(s,"PRIVSTRING NULL!!\r\n"); else s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.Mpriv_cnt[i], @@ -864,6 +883,7 @@ int zero_privop_counts(char *buf) privcnt.ssm = 0; privcnt.rsm = 0; privcnt.rfi = 0; privcnt.bsw0 = 0; privcnt.bsw1 = 0; privcnt.cover = 0; + privcnt.fc = 0; privcnt.cpuid = 0; for (i=0; i < 64; i++) privcnt.Mpriv_cnt[i] = 0; for (j=0; j < 128; j++) from_cr_cnt[j] = 0; for (j=0; j < 128; j++) to_cr_cnt[j] = 0; @@ -871,12 +891,61 @@ int zero_privop_counts(char *buf) return s - buf; } +#ifdef PRIVOP_ADDR_COUNT + +extern struct privop_addr_count privop_addr_counter[]; + +void privop_count_addr(unsigned long iip, int inst) +{ + struct privop_addr_count *v = &privop_addr_counter[inst]; + int i; + + for (i = 0; i < PRIVOP_COUNT_NADDRS; i++) { + if (!v->addr[i]) { v->addr[i] = iip; v->count[i]++; return; } + else if (v->addr[i] == iip) { v->count[i]++; return; } + } + v->overflow++;; +} + +int dump_privop_addrs(char *buf) +{ + int i,j; + char *s = buf; + s += sprintf(s,"Privop addresses:\r\n"); + for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) { + struct privop_addr_count *v = &privop_addr_counter[i]; + s += sprintf(s,"%s:\n",v->instname); + for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) { + if (!v->addr[j]) break; + s += sprintf(s," @%p #%ld\n",v->addr[j],v->count[j]); + } + if (v->overflow) + s += sprintf(s," other #%ld\n",v->overflow); + } + return s - buf; +} + +void zero_privop_addrs(void) +{ + int i,j; + for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) { + struct privop_addr_count *v = &privop_addr_counter[i]; + for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) + v->addr[j] = v->count[j] = 0; + v->overflow = 0; + } +} +#endif + #define TMPBUFLEN 8*1024 int dump_privop_counts_to_user(char __user *ubuf, int len) { char buf[TMPBUFLEN]; int n = dump_privop_counts(buf); +#ifdef PRIVOP_ADDR_COUNT + n += dump_privop_addrs(buf + n); +#endif if (len < TMPBUFLEN) return -1; if (__copy_to_user(ubuf,buf,n)) return -1; return n; @@ -887,6 +956,9 @@ int zero_privop_counts_to_user(char __user *ubuf, int len) char buf[TMPBUFLEN]; int n = zero_privop_counts(buf); +#ifdef PRIVOP_ADDR_COUNT + zero_privop_addrs(); +#endif if (len < TMPBUFLEN) return -1; if (__copy_to_user(ubuf,buf,n)) return -1; return n; diff --git a/xen/arch/ia64/vcpu.c b/xen/arch/ia64/vcpu.c index d1769a20c3..f5c3f458b3 100644 --- a/xen/arch/ia64/vcpu.c +++ b/xen/arch/ia64/vcpu.c @@ -37,6 +37,17 @@ typedef union { #define STATIC +#ifdef PRIVOP_ADDR_COUNT +struct privop_addr_count privop_addr_counter[PRIVOP_COUNT_NINSTS] = { + { "rsm", { 0 }, { 0 }, 0 }, + { "ssm", { 0 }, { 0 }, 0 } +}; +extern void privop_count_addr(unsigned long addr, int inst); +#define PRIVOP_COUNT_ADDR(regs,inst) privop_count_addr(regs->cr_iip,inst) +#else +#define PRIVOP_COUNT_ADDR(x,y) do {} while (0) +#endif + unsigned long vcpu_verbose = 0; #define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0) @@ -77,30 +88,20 @@ vcpu_set_gr(VCPU *vcpu, unsigned reg, UINT64 value) IA64FAULT vcpu_set_ar(VCPU *vcpu, UINT64 reg, UINT64 val) { if (reg == 44) return (vcpu_set_itc(vcpu,val)); - if (reg == 27) return (IA64_ILLOP_FAULT); - if (reg > 7) return (IA64_ILLOP_FAULT); - PSCB(vcpu,krs[reg]) = val; -#if 0 -// for now, privify kr read's so all kr accesses are privileged - switch (reg) { - case 0: asm volatile ("mov ar.k0=%0" :: "r"(val)); break; - case 1: asm volatile ("mov ar.k1=%0" :: "r"(val)); break; - case 2: asm volatile ("mov ar.k2=%0" :: "r"(val)); break; - case 3: asm volatile ("mov ar.k3=%0" :: "r"(val)); break; - case 4: asm volatile ("mov ar.k4=%0" :: "r"(val)); break; - case 5: asm volatile ("mov ar.k5=%0" :: "r"(val)); break; - case 6: asm volatile ("mov ar.k6=%0" :: "r"(val)); break; - case 7: asm volatile ("mov ar.k7=%0" :: "r"(val)); break; - case 27: asm volatile ("mov ar.cflg=%0" :: "r"(val)); break; - } -#endif + else if (reg == 27) return (IA64_ILLOP_FAULT); + else if (reg == 24) + printf("warning: setting ar.eflg is a no-op; no IA-32 support\n"); + else if (reg > 7) return (IA64_ILLOP_FAULT); + else PSCB(vcpu,krs[reg]) = val; return IA64_NO_FAULT; } IA64FAULT vcpu_get_ar(VCPU *vcpu, UINT64 reg, UINT64 *val) { - if (reg > 7) return (IA64_ILLOP_FAULT); - *val = PSCB(vcpu,krs[reg]); + if (reg == 24) + printf("warning: getting ar.eflg is a no-op; no IA-32 support\n"); + else if (reg > 7) return (IA64_ILLOP_FAULT); + else *val = PSCB(vcpu,krs[reg]); return IA64_NO_FAULT; } @@ -124,6 +125,7 @@ IA64FAULT vcpu_reset_psr_sm(VCPU *vcpu, UINT64 imm24) struct ia64_psr psr, imm, *ipsr; REGS *regs = vcpu_regs(vcpu); + PRIVOP_COUNT_ADDR(regs,_RSM); // TODO: All of these bits need to be virtualized // TODO: Only allowed for current vcpu __asm__ __volatile ("mov %0=psr;;" : "=r"(psr) :: "memory"); @@ -158,6 +160,7 @@ IA64FAULT vcpu_set_psr_sm(VCPU *vcpu, UINT64 imm24) REGS *regs = vcpu_regs(vcpu); UINT64 mask, enabling_interrupts = 0; + PRIVOP_COUNT_ADDR(regs,_SSM); // TODO: All of these bits need to be virtualized __asm__ __volatile ("mov %0=psr;;" : "=r"(psr) :: "memory"); imm = *(struct ia64_psr *)&imm24; diff --git a/xen/arch/ia64/xenmisc.c b/xen/arch/ia64/xenmisc.c index fe9f3442d2..09dfc2a7b9 100644 --- a/xen/arch/ia64/xenmisc.c +++ b/xen/arch/ia64/xenmisc.c @@ -132,73 +132,6 @@ void free_page_type(struct pfn_info *page, unsigned int type) dummy(); } -/////////////////////////////// -// from arch/x86/pci.c -/////////////////////////////// - -int -pcibios_prep_mwi (struct pci_dev *dev) -{ - dummy(); -} - -/////////////////////////////// -// from arch/x86/pci-irq.c -/////////////////////////////// - -void pcibios_enable_irq(struct pci_dev *dev) -{ - dummy(); -} - -/////////////////////////////// -// from arch/ia64/pci-pc.c -/////////////////////////////// - -#include - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - dummy(); - return 0; -} - -int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL; -int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL; - -//struct pci_fixup pcibios_fixups[] = { { 0 } }; -struct pci_fixup pcibios_fixups[] = { { 0 } }; - -void -pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - dummy(); -} - -void -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - dummy(); -} - -void __devinit pcibios_fixup_bus(struct pci_bus *b) -{ - dummy(); -} - -void __init pcibios_init(void) -{ - dummy(); -} - -char * __devinit pcibios_setup(char *str) -{ - dummy(); - return 0; -} - /////////////////////////////// // from arch/ia64/traps.c /////////////////////////////// @@ -206,7 +139,7 @@ char * __devinit pcibios_setup(char *str) void show_registers(struct pt_regs *regs) { printf("*** ADD REGISTER DUMP HERE FOR DEBUGGING\n"); -} +} /////////////////////////////// // from common/keyhandler.c diff --git a/xen/arch/ia64/xentime.c b/xen/arch/ia64/xentime.c index 20d13eb7ef..a3790b4577 100644 --- a/xen/arch/ia64/xentime.c +++ b/xen/arch/ia64/xentime.c @@ -84,6 +84,17 @@ xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) { unsigned long new_itm; +#define HEARTBEAT_FREQ 16 // period in seconds +#ifdef HEARTBEAT_FREQ + static long count = 0; + if (!(++count & ((HEARTBEAT_FREQ*1024)-1))) { + printf("Heartbeat... iip=%p,psr.i=%d,pend=%d\n", + regs->cr_iip, + current->vcpu_info->arch.interrupt_delivery_enabled, + current->vcpu_info->arch.pending_interruption); + count = 0; + } +#endif #ifndef XEN if (unlikely(cpu_is_offline(smp_processor_id()))) { return IRQ_HANDLED; diff --git a/xen/include/asm-ia64/config.h b/xen/include/asm-ia64/config.h index 74dbb3a4e5..0a3672b18e 100644 --- a/xen/include/asm-ia64/config.h +++ b/xen/include/asm-ia64/config.h @@ -174,12 +174,6 @@ struct device { #endif }; -// from linux/include/linux/pci.h -struct pci_bus_region { - unsigned long start; - unsigned long end; -}; - // warning: unless search_extable is declared, the return value gets // truncated to 32-bits, causing a very strange error in privop handling struct exception_table_entry; diff --git a/xen/include/asm-ia64/vcpu.h b/xen/include/asm-ia64/vcpu.h index 6ee2e73dde..e3bcfbde79 100644 --- a/xen/include/asm-ia64/vcpu.h +++ b/xen/include/asm-ia64/vcpu.h @@ -21,6 +21,21 @@ typedef struct pt_regs REGS; //#define vcpu_regs(vcpu) &((struct spk_thread_t *)vcpu)->thread_regs //#define vcpu_thread(vcpu) ((struct spk_thread_t *)vcpu) +#define PRIVOP_ADDR_COUNT +#ifdef PRIVOP_ADDR_COUNT +#define _RSM 0 +#define _SSM 1 +#define PRIVOP_COUNT_NINSTS 2 +#define PRIVOP_COUNT_NADDRS 30 + +struct privop_addr_count { + char *instname; + unsigned long addr[PRIVOP_COUNT_NADDRS]; + unsigned long count[PRIVOP_COUNT_NADDRS]; + unsigned long overflow; +}; +#endif + /* general registers */ extern UINT64 vcpu_get_gr(VCPU *vcpu, unsigned reg); extern IA64FAULT vcpu_set_gr(VCPU *vcpu, unsigned reg, UINT64 value); -- 2.30.2